# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1203+1.1069.324.88 -> 1.1204 
#	include/linux/acpi.h	1.17.1.4 -> 1.23   
#	include/linux/sysctl.h	1.23.1.24 -> 1.46   
#	drivers/acpi/pci_root.c	1.4.1.4 -> 1.8.1.1
#	     mm/page_alloc.c	1.56.1.14 -> 1.69   
#	include/linux/sched.h	1.33.1.10 -> 1.45   
#	     kernel/sysctl.c	1.19.1.11 -> 1.29   
#	drivers/char/agp/agpgart_be.c	1.35.1.21 -> 1.65   
#	drivers/acpi/tables.c	1.9.1.5 -> 1.19   
#	drivers/char/Config.in	1.36.1.30 -> 1.63   
#	   drivers/pci/pci.c	1.36.1.13 -> 1.46   
#	drivers/net/Makefile	1.29.1.14 -> 1.44   
#	arch/i386/kernel/mpparse.c	1.27.1.22 -> 1.46   
#	arch/i386/kernel/io_apic.c	1.27.1.9 -> 1.39   
#	arch/i386/kernel/pci-pc.c	1.30.1.7 -> 1.36   
#	include/linux/pci_ids.h	1.44.1.47 -> 1.85   
#	   drivers/net/tg3.c	1.61.2.91 -> 1.84   
#	drivers/char/agp/agp.h	1.18.1.9 -> 1.30   
#	drivers/scsi/Config.in	1.15.1.9 -> 1.26   
#	 include/linux/pci.h	1.34.1.3 -> 1.40   
#	 drivers/pci/pci.ids	1.44.1.7 -> 1.52   
#	  drivers/acpi/bus.c	1.18.1.10 -> 1.26   
#	   drivers/net/tg3.h	1.25.1.11 -> 1.33   
#	      fs/proc/base.c	1.12.1.6 -> 1.23   
#	            Makefile	1.190.7.24 -> 1.274  
#	drivers/char/drm/drmP.h	1.9.1.6 -> 1.16.1.1
#	drivers/scsi/Makefile	1.19.1.6 -> 1.27   
#	drivers/hotplug/acpiphp_glue.c	1.5.1.3 -> 1.7.1.1
#	drivers/acpi/Config.in	1.9.1.10 -> 1.24   
#	Documentation/Configure.help	1.162.1.83 -> 1.216  
#	arch/ia64/kernel/perfmon.c	1.7.2.2 -> 1.26   
#	drivers/char/Makefile	1.27.1.16 -> 1.41   
#	drivers/acpi/Makefile	1.16.1.2 -> 1.20   
#	arch/i386/kernel/pci-irq.c	1.20.1.7 -> 1.30   
#
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Sat May 15 13:03:17 2004
+++ b/Documentation/Configure.help	Sat May 15 13:03:17 2004
@@ -18640,6 +18640,11 @@
   purpose port, say Y here. See
   <http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
 
+Support for serial ports defined in ACPI namespace
+CONFIG_SERIAL_ACPI
+  If you wish to enable serial port discovery via the ACPI
+  namespace, say Y here.  If unsure, say N.
+
 Support for PowerMac serial ports
 CONFIG_MAC_SERIAL
   If you have Macintosh style serial ports (8 pin mini-DIN), say Y
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Sat May 15 13:03:17 2004
+++ b/Makefile	Sat May 15 13:03:17 2004
@@ -93,6 +93,7 @@
 
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
 	  -fno-strict-aliasing -fno-common
+CFLAGS += -g
 ifndef CONFIG_FRAME_POINTER
 CFLAGS += -fomit-frame-pointer
 endif
@@ -307,8 +308,7 @@
 	$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
 
 xconfig: symlinks
-	$(MAKE) -C scripts kconfig.tk
-	wish -f scripts/kconfig.tk
+	@echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***"
 
 menuconfig: include/linux/version.h symlinks
 	$(MAKE) -C scripts/lxdialog all
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	Sat May 15 13:03:17 2004
+++ b/drivers/acpi/bus.c	Sat May 15 13:03:17 2004
@@ -1405,16 +1405,14 @@
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
 		result = acpi_bus_get_status(device);
-		if (result)
-			goto end;
-		break;
+		if (!result)
+			break;
+		if (!device->status.present)
+			result = -ENOENT;
+		goto end;
 	default:
 		STRUCT_TO_INT(device->status) = 0x0F;
 		break;
-	}
-	if (!device->status.present) {
-		result = -ENOENT;
-		goto end;
 	}
 
 	/*
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
--- a/drivers/char/Config.in	Sat May 15 13:03:17 2004
+++ b/drivers/char/Config.in	Sat May 15 13:03:17 2004
@@ -24,6 +24,9 @@
       tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
       tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL
    fi
+   if [ "$CONFIG_ACPI" = "y" ]; then
+      bool '  Support for serial ports defined in ACPI namespace' CONFIG_SERIAL_ACPI
+   fi
 fi
 dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Sat May 15 13:03:17 2004
+++ b/drivers/char/agp/agp.h	Sat May 15 13:03:17 2004
@@ -538,10 +538,6 @@
 #define HP_ZX1_TCNFG		0x318
 #define HP_ZX1_PDIR_BASE	0x320
 
-/* HP ZX1 LBA registers */
-#define HP_ZX1_AGP_STATUS	0x64
-#define HP_ZX1_AGP_COMMAND	0x68
-
 /* ATI register */
 #define ATI_APBASE                  0x10
 #define ATI_GART_MMBASE_ADDR        0x14
diff -Nru a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
--- a/drivers/char/agp/agpgart_be.c	Sat May 15 13:03:16 2004
+++ b/drivers/char/agp/agpgart_be.c	Sat May 15 13:03:17 2004
@@ -45,6 +45,7 @@
 #include <linux/pagemap.h>
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
+#include <linux/acpi.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -217,10 +218,14 @@
 		agp_bridge.free_by_type(curr);
 		return;
 	}
-	if (curr->page_count != 0) {
-		for (i = 0; i < curr->page_count; i++) {
-			agp_bridge.agp_destroy_page((unsigned long)
-					 phys_to_virt(curr->memory[i]));
+	if (agp_bridge.cant_use_aperture) {
+		vfree(curr->vmptr);
+	} else {
+		if (curr->page_count != 0) {
+			for (i = 0; i < curr->page_count; i++) {
+				agp_bridge.agp_destroy_page((unsigned long)
+						 phys_to_virt(curr->memory[i]));
+			}
 		}
 	}
 	agp_free_key(curr->key);
@@ -229,6 +234,8 @@
 	MOD_DEC_USE_COUNT;
 }
 
+#define IN_VMALLOC(_x)	  (((_x) >= VMALLOC_START) && ((_x) < VMALLOC_END))
+
 #define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
 
 agp_memory *agp_allocate_memory(size_t page_count, u32 type)
@@ -263,18 +270,43 @@
 	      	MOD_DEC_USE_COUNT;
 		return NULL;
 	}
-	for (i = 0; i < page_count; i++) {
-		new->memory[i] = agp_bridge.agp_alloc_page();
 
-		if (new->memory[i] == 0) {
-			/* Free this structure */
-			agp_free_memory(new);
+	if (agp_bridge.cant_use_aperture) {
+		void *vmblock;
+		unsigned long vaddr;
+		struct page *page;
+
+		vmblock = __vmalloc(page_count << PAGE_SHIFT, GFP_KERNEL, PAGE_KERNEL);
+		if (vmblock == NULL) {
+			MOD_DEC_USE_COUNT;
 			return NULL;
 		}
-		new->memory[i] = virt_to_phys((void *) new->memory[i]);
-		new->page_count++;
-	}
+		new->vmptr = vmblock;
+		vaddr = (unsigned long) vmblock;
+
+		for (i = 0; i < page_count; i++, vaddr += PAGE_SIZE) {
+			page = vmalloc_to_page((void *) vaddr);
+			if (!page) {
+				MOD_DEC_USE_COUNT;
+				return NULL;
+			}
+			new->memory[i] = virt_to_phys(page_address(page));
+		}
+
+		new->page_count = page_count;
+	} else {
+		for (i = 0; i < page_count; i++) {
+			new->memory[i] = agp_bridge.agp_alloc_page();
 
+			if (new->memory[i] == 0) {
+				/* Free this structure */
+				agp_free_memory(new);
+				return NULL;
+			}
+			new->memory[i] = virt_to_phys((void *) new->memory[i]);
+			new->page_count++;
+		}
+	}
 	return new;
 }
 
@@ -287,26 +319,18 @@
 
 	temp = agp_bridge.current_size;
 
-	switch (agp_bridge.size_type) {
-	case U8_APER_SIZE:
+	if (agp_bridge.size_type == U8_APER_SIZE)
 		current_size = A_SIZE_8(temp)->size;
-		break;
-	case U16_APER_SIZE:
+	else if (agp_bridge.size_type ==  U16_APER_SIZE)
 		current_size = A_SIZE_16(temp)->size;
-		break;
-	case U32_APER_SIZE:
+	else if (agp_bridge.size_type ==  U32_APER_SIZE)
 		current_size = A_SIZE_32(temp)->size;
-		break;
-	case LVL2_APER_SIZE:
+	else if (agp_bridge.size_type ==  LVL2_APER_SIZE)
 		current_size = A_SIZE_LVL2(temp)->size;
-		break;
-	case FIXED_APER_SIZE:
+	else if (agp_bridge.size_type ==  FIXED_APER_SIZE)
 		current_size = A_SIZE_FIX(temp)->size;
-		break;
-	default:
+	else
 		current_size = 0;
-		break;
-	}
 
 	current_size -= (agp_memory_reserved / (1024*1024));
 
@@ -315,6 +339,9 @@
 
 /* Routine to copy over information structure */
 
+/* AGP bridge need not be PCI device, but DRM thinks it is. */
+static struct pci_dev fake_bridge_dev;
+
 int agp_copy_info(agp_kern_info * info)
 {
 	memset(info, 0, sizeof(agp_kern_info));
@@ -324,7 +351,7 @@
 	}
 	info->version.major = agp_bridge.version->major;
 	info->version.minor = agp_bridge.version->minor;
-	info->device = agp_bridge.dev;
+	info->device = agp_bridge.dev ? agp_bridge.dev : &fake_bridge_dev;
 	info->chipset = agp_bridge.type;
 	info->mode = agp_bridge.mode;
 	info->aper_base = agp_bridge.gart_bus_addr;
@@ -398,97 +425,104 @@
 
 /* Generic Agp routines - Start */
 
-static void agp_generic_agp_enable(u32 mode)
+static u32 agp_collect_device_status(u32 mode, u32 command)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch;
-	u8 cap_ptr;
+	struct pci_dev *device;
+	u8 agp;
+	u32 scratch;
 
-	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + 4,
-			      &command);
+	pci_for_each_dev(device) {
+		agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
 
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
+		/*
+		 * Ok, here we have a AGP device. Disable impossible 
+		 * settings, and adjust the readqueue to the minimum.
+		 */
+		pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
 
+		/* adjust RQ depth */
+		command =
+		    ((command & ~0xff000000) |
+		     min_t(u32, (mode & 0xff000000),
+			 min_t(u32, (command & 0xff000000),
+			     (scratch & 0xff000000))));
+
+		/* disable SBA if it's not supported */
+		if (!((command & 0x00000200) &&
+		      (scratch & 0x00000200) &&
+		      (mode & 0x00000200)))
+			command &= ~0x00000200;
+
+		/* disable FW if it's not supported */
+		if (!((command & 0x00000010) &&
+		      (scratch & 0x00000010) &&
+		      (mode & 0x00000010)))
+			command &= ~0x00000010;
 
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x00000010) &&
-			      (scratch & 0x00000010) &&
-			      (mode & 0x00000010)))
-				command &= ~0x00000010;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
+		if (!((command & 4) &&
+		      (scratch & 4) &&
+		      (mode & 4)))
+			command &= ~0x00000004;
+
+		if (!((command & 2) &&
+		      (scratch & 2) &&
+		      (mode & 2)))
+			command &= ~0x00000002;
+
+		if (!((command & 1) &&
+		      (scratch & 1) &&
+		      (mode & 1)))
+			command &= ~0x00000001;
 	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
 
-	if (command & 4) {
+	if (command & 4)
 		command &= ~3;	/* 4X */
+	if (command & 2)
+		command &= ~5;	/* 2X (8X for AGP3.0) */
+	if (command & 1)
+		command &= ~6;	/* 1X (4X for AGP3.0) */
+
+	return command;
+}
+
+static void agp_device_command(u32 command, int agp_v3)
+{
+	struct pci_dev *device;
+	int mode;
+
+	mode = command & 0x7;
+	if (agp_v3)
+		mode *= 4;
+
+	pci_for_each_dev(device) {
+		u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
+
+		printk(KERN_INFO PFX "Putting AGP V%d device at %s into %dx mode\n",
+				agp_v3 ? 3 : 2, device->slot_name, mode);
+		pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
 	}
-	if (command & 2) {
-		command &= ~5;	/* 2X */
-	}
-	if (command & 1) {
-		command &= ~6;	/* 1X */
-	}
+}
+
+static void agp_generic_agp_enable(u32 mode)
+{
+	u32 command;
+
+	pci_read_config_dword(agp_bridge.dev,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
+			      &command);
+
+	command = agp_collect_device_status(mode, command);
 	command |= 0x00000100;
 
 	pci_write_config_dword(agp_bridge.dev,
-			       agp_bridge.capndx + 8,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
 			       command);
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 0);
 }
 
 static int agp_generic_create_gatt_table(void)
@@ -3641,7 +3675,6 @@
 	struct pci_dev *device = NULL;
 	u32 command, scratch; 
 	u8 cap_ptr;
-	u8 agp_v3;
 	u8 v3_devs=0;
 
 	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
@@ -3674,77 +3707,14 @@
 	}
 
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
-
-	/*
-	 * PASS2: go through all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
-					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-			agp_v3 = (scratch & (1<<3) ) >>3;
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
-				command &= ~0x200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
-				command &= ~0x10;
-
-			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
-				command &= ~2;		/* 8x */
-				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
-			}
-
-			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
-				command &= ~1;		/* 4x */
-				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
-			}
-		}
-	}
-	/*
-	 * PASS3: Figure out the 8X/4X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 2)
-		command &= ~5;	/* 8X */
-
-	if (command & 1)
-		command &= ~6;	/* 4X */
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + PCI_AGP_STATUS, &command);
 
+	command = agp_collect_device_status(mode, command);
 	command |= 0x100;
 
-	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command);
-
-	/*
-	 * PASS4: Go through all AGP devices and update the
-	 *        command registers.
-	 */
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + PCI_AGP_COMMAND, command);
 
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 1);
 }
 
 
@@ -4457,7 +4427,7 @@
 
 	/* Fill in the mode register */
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &agp_bridge.mode);
 
 	pci_read_config_byte(agp_bridge.dev,
@@ -4607,104 +4577,23 @@
 
 static void serverworks_agp_enable(u32 mode)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch, cap_id;
-	u8 cap_ptr;
+	u32 command;
 
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &command);
 
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW */
-			command &= ~0x00000010;
-
-			command &= ~0x00000008;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
-	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
+	command = agp_collect_device_status(mode, command);
 
-	if (command & 4) {
-		command &= ~3;	/* 4X */
-	}
-	if (command & 2) {
-		command &= ~5;	/* 2X */
-	}
-	if (command & 1) {
-		command &= ~6;	/* 1X */
-	}
+	command &= ~0x00000010;	/* disable FW */
+	command &= ~0x00000008;
 	command |= 0x00000100;
 
 	pci_write_config_dword(serverworks_private.svrwrks_dev,
-			       agp_bridge.capndx + 8,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
 			       command);
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 0);
 }
 
 static int __init serverworks_setup (struct pci_dev *pdev)
@@ -5131,6 +5020,7 @@
 static struct _hp_private {
 	volatile u8 *ioc_regs;
 	volatile u8 *lba_regs;
+	int lba_cap_offset;
 	u64 *io_pdir;		// PDIR for entire IOVA
 	u64 *gatt;		// PDIR just for GART (subset of above)
 	u64 gatt_entries;
@@ -5183,6 +5073,7 @@
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
+		/* Normal case when no AGP device in system */
 	    	hp->gatt = 0;
 		hp->gatt_entries = 0;
 		printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
@@ -5228,12 +5119,13 @@
 	return 0;
 }
 
-static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa)
+static int __init hp_zx1_ioc_init(u64 hpa)
 {
 	struct _hp_private *hp = &hp_private;
 
-	hp->ioc_regs = ioremap(ioc_hpa, 1024);
-	hp->lba_regs = ioremap(lba_hpa, 256);
+	hp->ioc_regs = ioremap(hpa, 1024);
+	if (!hp->ioc_regs)
+		return -ENOMEM;
 
 	/*
 	 * If the IOTLB is currently disabled, we can take it over.
@@ -5247,6 +5139,50 @@
 	return hp_zx1_ioc_shared();
 }
 
+static int
+hp_zx1_lba_find_capability(volatile u8 *hpa, int cap)
+{
+	u16 status;
+	u8 pos, id;
+	int ttl = 48;
+
+	status = INREG16(hpa, PCI_STATUS);
+	if (!(status & PCI_STATUS_CAP_LIST))
+		return 0;
+	pos = INREG8(hpa, PCI_CAPABILITY_LIST);
+	while (ttl-- && pos >= 0x40) {
+		pos &= ~3;
+		id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
+	}
+	return 0;
+}
+
+static int __init hp_zx1_lba_init(u64 hpa)
+{
+	struct _hp_private *hp = &hp_private;
+	int cap;
+
+	hp->lba_regs = ioremap(hpa, 256);
+	if (!hp->lba_regs)
+		return -ENOMEM;
+
+	hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
+
+	cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
+	if (cap != PCI_CAP_ID_AGP) {
+		printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
+			cap, hp->lba_cap_offset);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static int hp_zx1_fetch_size(void)
 {
 	int size;
@@ -5262,7 +5198,7 @@
 	struct _hp_private *hp = &hp_private;
 
 	agp_bridge.gart_bus_addr = hp->gart_base;
-	agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
+	agp_bridge.mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
 		OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE,
@@ -5282,10 +5218,13 @@
 {
 	struct _hp_private *hp = &hp_private;
 
-	if (hp->io_pdir_owner)
-		OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
-	iounmap((void *) hp->ioc_regs);
-	iounmap((void *) hp->lba_regs);
+	if (hp->ioc_regs) {
+		if (hp->io_pdir_owner)
+			OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
+		iounmap((void *) hp->ioc_regs);
+	}
+	if (hp->lba_regs)
+		iounmap((void *) hp->lba_regs);
 }
 
 static void hp_zx1_tlbflush(agp_memory * mem)
@@ -5405,18 +5344,23 @@
 	struct _hp_private *hp = &hp_private;
 	u32 command;
 
-	command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
+	command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
 
 	command = agp_collect_device_status(mode, command);
 	command |= 0x00000100;
 
-	OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command);
+	OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
 
 	agp_device_command(command, 0);
 }
 
 static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa)
 {
+	struct _hp_private *hp = &hp_private;
+	int error;
+
+	memset(hp, 0, sizeof(*hp));
+
 	agp_bridge.dev_private_data = NULL;
 	agp_bridge.size_type = FIXED_APER_SIZE;
 	agp_bridge.needs_scratch_page = FALSE;
@@ -5441,7 +5385,16 @@
 	fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
 	fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
 
-	return hp_zx1_ioc_init(ioc_hpa, lba_hpa);
+	error = hp_zx1_ioc_init(ioc_hpa);
+	if (error)
+		goto fail;
+
+	error = hp_zx1_lba_init(lba_hpa);
+
+fail:
+	if (error)
+		hp_zx1_cleanup();
+	return error;
 }
 
 static acpi_status __init hp_zx1_gart_probe(acpi_handle obj, u32 depth, void *context, void **ret)
@@ -5455,7 +5408,7 @@
 
 	status = acpi_hp_csr_space(obj, &lba_hpa, &length);
 	if (ACPI_FAILURE(status))
-		return AE_OK;
+		return AE_OK; /* keep looking for another bridge */
 
 	/* Look for an enclosing IOC scope and find its CSR space */
 	handle = obj;
@@ -5491,7 +5444,7 @@
 		(char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
 
 	hp_zx1_gart_found = 1;
-	return AE_CTRL_TERMINATE;
+	return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
 }
 
 static int __init
@@ -6473,7 +6426,6 @@
 	  "IGP9100/M",
 	  ati_generic_setup },
 #endif /* CONFIG_AGP_ATI */
-
 	{ 0, }, /* dummy final entry, always present */
 };
 
@@ -6556,7 +6508,6 @@
 	return -ENODEV;
 }
 
-
 /* Supported Device Scanning routine */
 
 static int __init agp_find_supported_device(void)
@@ -6884,7 +6835,7 @@
 
 	/* Fill in the mode register */
 	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &agp_bridge.mode);
 
 	/* probe for known chipsets */
@@ -7102,7 +7053,8 @@
 
 	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
 	
-	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
+	if (agp_bridge.dev)
+		pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
 	return 0;
 }
 
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	Sat May 15 13:03:17 2004
+++ b/drivers/pci/pci.c	Sat May 15 13:03:17 2004
@@ -1061,8 +1061,14 @@
 {
 	unsigned int pos, reg, next;
 	u32 l, sz;
+	u16 cmd;
 	struct resource *res;
 
+	/* Disable I/O & memory decoding while we size the BARs. */
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_write_config_word(dev, PCI_COMMAND,
+		cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
 	for(pos=0; pos<howmany; pos = next) {
 		next = pos+1;
 		res = &dev->resource[pos];
@@ -1127,13 +1133,16 @@
 		if (sz && sz != 0xffffffff) {
 			sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
 			if (!sz)
-				return;
+				goto out;
 			res->flags = (l & PCI_ROM_ADDRESS_ENABLE) |
 			  IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
 			res->start = l & PCI_ROM_ADDRESS_MASK;
 			res->end = res->start + (unsigned long) sz;
 		}
 	}
+
+out:
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
 }
 
 void __devinit pci_read_bridge_bases(struct pci_bus *child)
@@ -2066,16 +2075,16 @@
 	int			map, block;
 
 	if ((page = pool_find_page (pool, dma)) == 0) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
+		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
 			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, (int) (dma & 0xffffffff));
+			pool->name, vaddr, (unsigned long) dma);
 		return;
 	}
 #ifdef	CONFIG_PCIPOOL_DEBUG
 	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
+		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
 			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, (int) (dma & 0xffffffff));
+			pool->name, vaddr, (unsigned long) dma);
 		return;
 	}
 #endif
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h	Sat May 15 13:03:16 2004
+++ b/include/linux/sysctl.h	Sat May 15 13:03:16 2004
@@ -157,6 +157,7 @@
 	VM_MAPPED_RATIO=20,     /* amount of unfreeable pages that triggers swapout */
 	VM_LAPTOP_MODE=21,	/* kernel in laptop flush mode */
 	VM_BLOCK_DUMP=22,	/* dump fs activity to log */
+	VM_HUGETLB_PAGES=23,	/* int: Number of available Huge Pages */
 };
 
 
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c	Sat May 15 13:03:16 2004
+++ b/kernel/sysctl.c	Sat May 15 13:03:16 2004
@@ -31,6 +31,7 @@
 #include <linux/sysrq.h>
 #include <linux/highuid.h>
 #include <linux/swap.h>
+#include <linux/hugetlb.h>
 
 #include <asm/uaccess.h>
 
@@ -315,6 +316,10 @@
 	 &laptop_mode, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_BLOCK_DUMP, "block_dump",
 	 &block_dump, sizeof(int), 0644, NULL, &proc_dointvec},
+#ifdef CONFIG_HUGETLB_PAGE
+	{VM_HUGETLB_PAGES, "nr_hugepages", &htlbpage_max, sizeof(int), 0644, NULL,
+	&hugetlb_sysctl_handler},
+#endif
 	{0}
 };
 
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Sat May 15 13:03:16 2004
+++ b/mm/page_alloc.c	Sat May 15 13:03:16 2004
@@ -79,11 +79,11 @@
 /*
  * Temporary debugging check.
  */
-#define BAD_RANGE(zone, page)						\
-(									\
-	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size))	\
-	|| (((page) - mem_map) < (zone)->zone_start_mapnr)		\
-	|| ((zone) != page_zone(page))					\
+#define BAD_RANGE(zone, page)						     \
+(									     \
+	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
+	|| (((page) - mem_map) < (zone)->zone_start_mapnr)		     \
+	|| ((zone) != page_zone(page))					     \
 )
 
 /*
@@ -633,7 +633,7 @@
  		unsigned long nr, total, flags;
 
 		total = 0;
-		if (zone->size) {
+		if (zone->realsize) {
 			spin_lock_irqsave(&zone->lock, flags);
 		 	for (order = 0; order < MAX_ORDER; order++) {
 				head = &(zone->free_area + order)->free_list;
@@ -665,13 +665,44 @@
 /*
  * Builds allocation fallback zone lists.
  */
-static inline void build_zonelists(pg_data_t *pgdat)
+static int __init build_zonelists_node(pg_data_t *pgdat, zonelist_t *zonelist, int j, int k)
 {
-	int i, j, k;
+	zone_t *zone;
+	switch (k) {
+	default:
+		BUG();
+		/*
+		 * fallthrough:
+		 */
+	case ZONE_HIGHMEM:
+		zone = pgdat->node_zones + ZONE_HIGHMEM;
+		if (zone->realsize) {
+#ifndef CONFIG_HIGHMEM
+			BUG();
+#endif
+			zonelist->zones[j++] = zone;
+		}
+	case ZONE_NORMAL:
+		zone = pgdat->node_zones + ZONE_NORMAL;
+		if (zone->realsize)
+			zonelist->zones[j++] = zone;
+	case ZONE_DMA:
+		zone = pgdat->node_zones + ZONE_DMA;
+		if (zone->realsize)
+			zonelist->zones[j++] = zone;
+	}
+
+	return j;
+}
+
+static void __init build_zonelists(pg_data_t *pgdat)
+{
+	int i, j, k, node, local_node;
 
+	local_node = pgdat->node_id;
+	printk("Building zonelist for node : %d\n", local_node);
 	for (i = 0; i <= GFP_ZONEMASK; i++) {
 		zonelist_t *zonelist;
-		zone_t *zone;
 
 		zonelist = pgdat->node_zonelists + i;
 		memset(zonelist, 0, sizeof(*zonelist));
@@ -683,33 +714,32 @@
 		if (i & __GFP_DMA)
 			k = ZONE_DMA;
 
-		switch (k) {
-			default:
-				BUG();
-			/*
-			 * fallthrough:
-			 */
-			case ZONE_HIGHMEM:
-				zone = pgdat->node_zones + ZONE_HIGHMEM;
-				if (zone->size) {
-#ifndef CONFIG_HIGHMEM
-					BUG();
-#endif
-					zonelist->zones[j++] = zone;
-				}
-			case ZONE_NORMAL:
-				zone = pgdat->node_zones + ZONE_NORMAL;
-				if (zone->size)
-					zonelist->zones[j++] = zone;
-			case ZONE_DMA:
-				zone = pgdat->node_zones + ZONE_DMA;
-				if (zone->size)
-					zonelist->zones[j++] = zone;
-		}
+ 		j = build_zonelists_node(pgdat, zonelist, j, k);
+ 		/*
+ 		 * Now we build the zonelist so that it contains the zones
+ 		 * of all the other nodes.
+ 		 * We don't want to pressure a particular node, so when
+ 		 * building the zones for node N, we make sure that the
+ 		 * zones coming right after the local ones are those from
+ 		 * node N+1 (modulo N)
+ 		 */
+ 		for (node = local_node + 1; node < numnodes; node++)
+ 			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
+ 		for (node = 0; node < local_node; node++)
+ 			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
+ 
 		zonelist->zones[j++] = NULL;
 	} 
 }
 
+void __init build_all_zonelists(void)
+{
+	int i;
+
+	for(i = 0 ; i < numnodes ; i++)
+		build_zonelists(NODE_DATA(i));
+}
+
 /*
  * Helper functions to size the waitqueue hash table.
  * Essentially these want to choose hash table sizes sufficiently
@@ -752,6 +782,31 @@
 	return ffz(~size);
 }
 
+static unsigned long memmap_init(struct page *start, struct page *end,
+	int zone, unsigned long start_paddr, int highmem) 
+{
+	struct page *page;
+
+	for (page = start; page < end; page++) {
+		set_page_zone(page, zone);
+		set_page_count(page, 0);
+		SetPageReserved(page);
+		INIT_LIST_HEAD(&page->list);
+		if (!highmem)
+			set_page_address(page, __va(start_paddr));
+		start_paddr += PAGE_SIZE;
+	}
+	return start_paddr;
+}
+
+#ifdef HAVE_ARCH_MEMMAP_INIT
+#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
+	arch_memmap_init(memmap_init, start, end, zone, paddr, highmem)
+#else
+#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
+	memmap_init(start, end, zone, paddr, highmem)
+#endif
+
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
 
 /*
@@ -773,10 +828,8 @@
 		BUG();
 
 	totalpages = 0;
-	for (i = 0; i < MAX_NR_ZONES; i++) {
-		unsigned long size = zones_size[i];
-		totalpages += size;
-	}
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		totalpages += zones_size[i];
 	realtotalpages = totalpages;
 	if (zholes_size)
 		for (i = 0; i < MAX_NR_ZONES; i++)
@@ -785,7 +838,7 @@
 	printk("On node %d totalpages: %lu\n", nid, realtotalpages);
 
 	/*
-	 * Some architectures (with lots of mem and discontinous memory
+	 * Some architectures (with lots of mem and discontigous memory
 	 * maps) have to search for a good mem_map area:
 	 * For discontigmem, the conceptual mem map array starts from 
 	 * PAGE_OFFSET, we need to align the actual array onto a mem map 
@@ -798,7 +851,7 @@
 			MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
 	}
 	*gmap = pgdat->node_mem_map = lmem_map;
-	pgdat->node_size = totalpages;
+	pgdat->node_size = 0;
 	pgdat->node_start_paddr = zone_start_paddr;
 	pgdat->node_start_mapnr = (lmem_map - mem_map);
 	pgdat->nr_zones = 0;
@@ -815,7 +868,7 @@
 		if (zholes_size)
 			realsize -= zholes_size[j];
 
-		printk("zone(%lu): %lu pages.\n", j, size);
+		printk("zone(%lu): %lu pages.\n", j, realsize);
 		zone->size = size;
 		zone->realsize = realsize;
 		zone->name = zone_names[j];
@@ -826,6 +879,7 @@
 		 zone->nr_active_pages = zone->nr_inactive_pages = 0;
 
 
+		pgdat->node_size += realsize;
 		if (!size)
 			continue;
 
@@ -886,16 +940,10 @@
 		 * up by free_all_bootmem() once the early boot process is
 		 * done. Non-atomic initialization, single-pass.
 		 */
-		for (i = 0; i < size; i++) {
-			struct page *page = mem_map + offset + i;
-			set_page_zone(page, nid * MAX_NR_ZONES + j);
-			set_page_count(page, 0);
-			SetPageReserved(page);
-			INIT_LIST_HEAD(&page->list);
-			if (j != ZONE_HIGHMEM)
-				set_page_address(page, __va(zone_start_paddr));
-			zone_start_paddr += PAGE_SIZE;
-		}
+		zone_start_paddr = MEMMAP_INIT(mem_map + offset,
+				mem_map + offset + size,
+				nid * MAX_NR_ZONES + j, zone_start_paddr,
+				(j == ZONE_HIGHMEM ? 1 : 0));
 
 		offset += size;
 		for (i = 0; ; i++) {
@@ -936,7 +984,6 @@
 			  (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
 		}
 	}
-	build_zonelists(pgdat);
 }
 
 void __init free_area_init(unsigned long *zones_size)